﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Moon.Sql
{
    public interface IMoonSql<T> : IMoonSql { }

    public interface IMoonSql : IDisposable
    {
        /// <summary>
        /// 数据库通用操作方法
        /// </summary>
        IDatabase Database { get; }
        #region Transaction
        /// <summary>
        /// 提供给跨库事务的方法 可直接用 RunTransaction
        /// </summary>
        /// <param name="isolationLevel"></param>
        void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted);
        /// <summary>
        /// 提供给跨库事务的方法 可直接用 RunTransaction
        /// </summary>
        /// <param name="isolationLevel"></param>
        void CommitTransaction();
        /// <summary>
        /// 提供给跨库事务的方法 可直接用 RunTransaction
        /// </summary>
        /// <param name="isolationLevel"></param>
        void RollbackTransaction();
        /// <summary>
        /// 事务
        /// </summary>
        /// <param name="action"></param>
        /// <param name="isolationLevel"></param>
        /// <returns></returns>
        RunTransactionResult RunTransaction(Action action, IsolationLevel isolationLevel = IsolationLevel.ReadCommitted);
        #endregion Transaction

        /// <summary>
        /// 执行前
        /// </summary>
        Action<ExecutingArgs> OnExecuting { get; set; }
        /// <summary>
        /// 执行后
        /// </summary>
        Action<ExecutedArgs> OnExecuted { get; set; }

        IInsertable<T> Insertable<T>();

        /// <summary>
        /// 添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        IInsertable<T> Insertable<T>(T t);

        /// <summary>
        /// 添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        IInsertable<T> Insertable<T>(List<T> list);

        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        IUpdateable<T> Updateable<T>(T t);

        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IUpdateable<T> Updateable<T>();
        /// <summary>
        /// 删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IDeleteable<T> Deleteable<T>();

        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pks"></param>
        /// <returns></returns>
        IDeleteable<T> Deleteable<T>(params object[] pks);

        #region Queryable
        /// <summary>
        /// 查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IQueryable<T> Queryable<T>();

        /// <summary>
        /// 多表连接，表1 别名 t1,表2 别名 t2
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <returns></returns>
        IQueryable<T, T2> Queryable<T, T2>();

        IQueryable<T, T2, T3> Queryable<T, T2, T3>();

        IQueryable<T, T2, T3, T4> Queryable<T, T2, T3, T4>();

        IQueryable<T, T2, T3, T4, T5> Queryable<T, T2, T3, T4, T5>();

        IQueryable<T, T2, T3, T4, T5, T6> Queryable<T, T2, T3, T4, T5, T6>();

        IQueryable<T, T2, T3, T4, T5, T6, T7> Queryable<T, T2, T3, T4, T5, T6, T7>();

        IQueryable<T, T2, T3, T4, T5, T6, T7, T8> Queryable<T, T2, T3, T4, T5, T6, T7, T8>();

        IQueryable<T, T2, T3, T4, T5, T6, T7, T8, T9> Queryable<T, T2, T3, T4, T5, T6, T7, T8, T9>();

        IQueryable<T, T2, T3, T4, T5, T6, T7, T8, T9, T10> Queryable<T, T2, T3, T4, T5, T6, T7, T8, T9, T10>();

        IQueryableUnion QueryableUnion();
        #endregion Queryable

        IQueryable<T, T2> Queryable<T, T2>(IQueryable<T> query1, IQueryable<T2> query2);

        IDbFirst DbFirst();
        ICodeFirst CodeFirst();
        IBatch CreateBatchSubmitContext();
    }
}
